﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

using System;
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Data.Entity;

using System.Data.Objects;
using System.Linq;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using System.Web;

using VideoClubGorbea.Model;


namespace VideoClubGorbea.TheMovieDbServices
{
    public class MovieDbServices : ITheMovieDB
    {
        private const string MOVIE_GET_INFO_URL = "http://api.themoviedb.org/2.1/Movie.getInfo/en/json/{0}/{1}";
        private const string MOVIE_IMDB_LOOKUP_URL = "http://api.themoviedb.org/2.1/Movie.imdbLookup/en/json/{0}/{1}";
        private const string MOVIE_SEARCH_URL = "http://api.themoviedb.org/2.1/Movie.search/en/json/{0}/{1}";
        private const string MOVIE_GET_IMAGES_URL = "http://api.themoviedb.org/2.1/Movie.getImages/en/json/{0}/{1}";
        private const string PERSON_SEARCH_URL = "http://api.themoviedb.org/2.1/Person.search/en/json/{0}/{1}";
        private const string PERSON_GET_INFO_URL = "http://api.themoviedb.org/2.1/Person.getInfo/en/json/{0}/{1}";
        public string ApiKey { get; set; }



        public MovieDbServices()
        {
            ApiKey = "2152252f53e30003f394860badcd8bc5";
        }

        async public Task<IEnumerable<Movie>> SearchMovie(string title)
        {
            List<Movie> result = new List<Movie>();
            try
            {
                string uriRequest = string.Format(MOVIE_SEARCH_URL, ApiKey, title);
                var data = await new WebClient().DownloadDataTaskAsync(new Uri(uriRequest));
                string json = System.Text.Encoding.UTF8.GetString(data);
                JArray movies = JArray.Parse(json);
                foreach (var item in movies)
                {
                    result.Add(CreateNewMovie(item));
                };
            }
            catch (System.Exception)
            { }
            return result;
        }

        private static Movie CreateNewMovie(JToken item)
        {
            var result = new Movie()
            {
                MovieID = item["id"].CheckValue<int>(),
                Title = item["original_name"].CheckValue<string>(),
                Posters = ExtractPosters(item),
                ForAdults = item["adult"].CheckValue<bool>(),
                OverView = item["overview"].CheckValue<string>(),
                Popularity = item["popularity"].CheckValue<int>(),
                Rating = item["rating"].CheckValue<double>(),
                ReleaseDate = item["released"].CheckDateValue(),
                Certification = item["certification"].CheckValue<string>(),
                Votes = item["votes"].Value<int>()
            };
            return result;
        }

        private static System.Collections.Generic.List<Image> ExtractPosters(JToken item)
        {
            var result = item["posters"]
                                .Children()["image"]
                                .Select(x => x["url"])
                                .Values<string>()
                                .Select(x =>
                                {
                                    return new Image()
                                    {
                                        Url = x.ToString()
                                    };
                                }).ToList();
            if (result.Count == 0)
            {
                result.Add(new Image() { Url = @"http://www.caselogic.es/DesktopModules/SharedCatalog/Images/image-not-found.gif" });
            }

            return result;
        }
    }

    public static class TheMovieDBExtensionMethods
    {
        public static T CheckValue<T>(this JToken token)
        {
            T x = ExtractValueOrReturnDefault<T>(token);
            return x;
        }
        public static System.DateTime CheckDateValue(this JToken token)
        {
            DateTime x = ExtractValueOrReturnDefault<DateTime>(token);
            if (x.Year == 1)
            {
                return System.DateTime.Now;
            }
            return x;
        }

        private static T ExtractValueOrReturnDefault<T>(JToken token)
        {
            T x;
            try
            {
                x = token.Value<T>();
            }
            catch (Exception)
            {
                x = default(T);

            }
            return x;
        }
    }



}
